import Vue from "vue";
import i18n from "@/lang/index";
import { listToMap } from "@/utils";

// service for vue dialog selector page
export const Dialog = {
  data() {
    return {
      visible: false,
      isInner: false, // 是否是二级弹出对话款
      callback: function (value) {
        console.log(value);
      },
    };
  },
  methods: {
    confirmSelector() {
      console.warn("confirm is not defined");
    },
    cancelSelector() {
      this.visible = false;
    },
  },
};

export const DataProvider = {
  data() {
    return {
      constQuery: {}, // 不可变动查询项
      loading: false,
      refresh: true,
      dataLoaded: false,
      list: [],
      total: 0,
      map: {},
    };
  },
  methods: {
    initData() {
      if (this.refresh) {
        this.queryData();
        return;
      }
      if (this.dataLoaded) {
        this.listLoaded();
        return;
      }
      this.queryData();
    },
    currentQuery(query) {
      var params = Object.assign({}, this.constQuery, query);
      for (var k in params) {
        params[k] = query[k] || this.constQuery[k];
      }
      return params;
    },
    requestList() {
      console.error("request data is not override!!!");
    },
    loadList(data) {
      this.list = [].concat(data.rows);
      this.total = data.total;
      this.map = listToMap(this.list, this.valueKey);
    },
    listLoaded() {},
    queryList(page) {
      const vm = this;
      this.loading = true;
      this.requestList(page).then((data) => {
        vm.loadList(data);
        vm.loading = false;
        vm.dataLoaded = true;
        vm.listLoaded();
      });
    },
    queryOther() {},
    queryData() {
      this.queryList();
      this.queryOther();
    },
  },
};

export const Selector = {
  mixins: [Dialog],
  is_tree_selector: false,
  data() {
    return {
      multiple: false, // 是否多选
      valueKey: "code",
      selections: [],
      value: [],
    };
  },
  methods: {
    listLoaded() {
      this.clearValue();
      this.setValue(this.value);
    },
    confirmSelector() {
      var values = this.selections;
      if (!values || values.length === 0) {
        this.$message({ message: "请选择有效的数据！", type: "warning" });
      }
      if (this.multiple) {
        this.callback(values);
      } else {
        this.callback(values.pop());
      }
      this.visible = false;
    },
    indexOfSelection(row) {
      for (var i = 0; i < this.selections.length; i++) {
        if (this.selections[i][this.valueKey] === row[this.valueKey]) {
          return i;
        }
      }
      return -1;
    },
    rowByKey(v) {
      return this.map[v];
      // for (var i = 0; i < this.list.length; i++) {
      //   const row = this.list[i]
      //   if (row[this.valueKey] === v) {
      //     return row
      //   }
      // }
      // return null
    },
    rowChecked(row) {
      var index = this.indexOfSelection(row);
      return index >= 0;
    },
    rowCheckable() {
      return true;
    },
    rowCheck(row) {
      if (!this.rowCheckable(row)) {
        return;
      }
      if (!this.multiple) {
        this.selections = [row];
        return;
      }
      var index = this.indexOfSelection(row);
      if (index >= 0) {
        this.selections.splice(index, 1);
      } else {
        this.selections.push(row);
      }
    },
    rowClick(row) {
      this.rowCheck(row);
    },
    itemDblClick(row) {
      this.selections = [row];
      this.confirmSelector();
    },
    clearValue() {
      this.selections = [];
    },
    setSelected(row) {
      if (!row || !row[this.valueKey]) {
        return;
      }
      this.selections.push(row);
    },
    setValue(key) {
      if (!key) {
        return;
      }
      if (this.multiple && key.length === 0) {
        return;
      }
      if (!this.multiple) {
        this.setSelected(this.rowByKey(key));
        return;
      }
      for (var j = 0; j < key.length; j++) {
        const v = key[j];
        this.setSelected(this.rowByKey(v));
      }
    },
  },
};

export const TableSelector = {
  mixins: [DataProvider, Selector],
  data() {
    return {
      tableName: "table",
      tableRef: null,
    };
  },
  updated() {
    this.listLoaded();
  },
  methods: {
    getTableRef() {
      this.tableRef = this.tableRef || this.$refs[this.tableName];
      if (this.tableRef) {
        return this.tableRef;
      }
      console.error(`tableRef is null ,table name is : ${this.tableName}`);
    },
    rowClick(row) {
      this.rowCheck(row);
      const table = this.getTableRef();
      if (this.multiple) {
        table.toggleRowSelection(row);
        return;
      }
      table.clearSelection();
      table.toggleRowSelection(row, true);
    },
    rowDblclick(row) {
      this.selections = [row];
      this.confirmSelector();
    },
    rowSelect(values, row) {
      this.rowClick(row);
    },
    selectionChange(values) {
      this.selections = values;
    },
    clearValue() {
      if (this.selections.length > 0) {
        this.getTableRef().clearSelection();
      }
      // this.selections = []
    },
    setSelected(row) {
      if (!row || !row[this.valueKey]) {
        return;
      }
      this.getTableRef().toggleRowSelection(row, true);
      // this.selections.push(row)
    },
  },
};

export const TreeSelector = {
  mixins: [DataProvider, Selector],
  data() {
    return {
      parentValueKey: "parent_code",
      rootValue: "root",
    };
  },
  computed: {
    treeData() {
      return this.listToTree(this.list);
    },
  },
  methods: {
    listToTree(list) {
      const root = [];
      const { valueKey, parentValueKey, rootValue } = this;
      for (var i = 0; i < list.length; i++) {
        const parent = list[i];
        const children = list.filter((item) => {
          return parent[valueKey] === item[parentValueKey];
        });
        if (children.length !== 0) {
          parent.children = children;
        }
        if (rootValue === parent[parentValueKey]) {
          root.push(parent);
        }
      }
      return root;
    },
    rowClass(row) {
      return {
        "selectable-node": this.rowCheckable(row),
        "selected-node": this.rowChecked(row),
      };
    },
  },
};

export const SelectorConstructor = function (selectorVue) {
  const { is_tree_selector } = selectorVue;
  const ParentVue = is_tree_selector ? TreeSelector : TableSelector;
  var constructor = Vue.extend(
    Object.assign(selectorVue, { mixins: [ParentVue], i18n })
  );

  var instance;
  const initInstance = () => {
    instance = new constructor({
      el: document.createElement("div"),
    });
    document.body.appendChild(instance.$el);
  };
  // var first = false
  if (instance === undefined || instance === null) {
    initInstance();

    Vue.nextTick(() => {
      // instance.initData()
      instance.visible = false;
    });
    // first = true
  }

  const show = (options, callback, value) => {
    // callback = callback || options.callback
    // value = value || options.value
    // if (callback) {
    instance.callback = callback || options.callback || instance.callback;
    instance.value = value || options.value || [];
    // }
    instance.refresh = options.refresh || false;
    if (options.valueKey) {
      instance.valueKey = options.valueKey;
    }
    if (options.query) {
      instance.constQuery = options.query;
    }
    if (options.isInner !== undefined && options.isInner !== null) {
      instance.isInner = options.isInner;
    }
    if (options.multiple !== undefined && options.multiple !== null) {
      instance.multiple = options.multiple;
    }

    if (options.params) {
      Object.assign(instance, options.params);
    }
    // if (value) {
    // instance.selections = [...value]
    // }
    // var parent = options.container || document.body // todo
    // parent.appendChild(instance.$el)
    // instance.queryData()

    Vue.nextTick(() => {
      instance.visible = true;
      instance.initData();
    });
  };
  return show;
};

export default SelectorConstructor;
